package keter.framework.web.controller;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.google.common.html.HtmlEscapers;
import com.jfinal.kit.JsonKit;

import keter.framework.model.base.BaseModel;

public abstract class AbstractBaseController {
    
    /**
     * Logger for this class
     */
    private static final Logger logger = LoggerFactory.getLogger(AbstractBaseController.class);
    
    public static class Routes{
        public static final String Index = "";
        public static final String List = "/list";
        public static final String Add = "/add";
        public static final String GetAll = "/getall";
        public static final String GetPaged = "/get/{pageNumber}/{pageSize}";
        public static final String Get = "/get/{id}";
//        public static final String View = "/view/{id}";
        public static final String Update = "/update";
//        public static final String Update = "/update/{id}";
        public static final String Delete = "/delete";
//        public static final String Delete = "/delete/{id}";
        public static final String Upload = "/upload";
        public static final String Download = "/download/{fileId}";
    }
    
    public String success() {
        /* 前台消息map */
        Map<String, String> ajaxMap = Maps.newHashMap();
        // 构造默认返回消息
        ajaxMap.put("success", "true");
        ajaxMap.put("message", "SUCCESS");
        return mapToJson(ajaxMap);
    }
    
    private String mapToJson(Map map){
    	return JSON.toJSONString(map);
    }
    
    /**
     * 操作成功返回前台消息
     * @param message
     * @return 
     * @author  gulixing@msn.com
     * @date    2015年9月16日
     */
    public String success(String message) {
    	/* 前台消息map */
    	Map<String, String> ajaxMap = Maps.newHashMap();
    	// 构造默认返回消息
    	ajaxMap.put("success", "true");
    	ajaxMap.put("message", message);
    	return mapToJson(ajaxMap);
    }
    
    /**
     * 操作成功返回前台消息：需给出错误描述
     * @param message
     * @return 
     * @author  gulixing@msn.com
     * @date    2015年9月16日
     */
    public String error(String message) {
    	Map<String, String> ajaxMap = Maps.newHashMap();
    	// 构造默认返回消息
    	ajaxMap.put("message", message);
    	return mapToJson(ajaxMap);
    }

    /**
     * <p>Method ：redirectToUrl
     * <p>Description : 重定向(GET)
     *
     * @param action
     * @return 
     * @author  顾力行-gulixing@msn.com
     */
    public static String redirectToUrl(String action) {
        return "redirect:" + action;
    }
    
    public static ModelAndView redirectToView(String view) {
        return new ModelAndView("redirect:" + view);
    }
    
    /**
     * <p>Method ：forwardToUrl
     * <p>Description : 服务器内部转发(地址栏不变)
     *
     * @param action
     * @return 
     * @author  顾力行-gulixing@msn.com
     */
    public static String forwardToUrl(String action) {
		return "forward:" + action;
	}
	

    /**
     * <p>Method ：defaultPage
     * <p>Description : 获取当前模块默认的jsp位置
     * @return 
     * @author  顾力行-gulixing@msn.com
     */
    public String getDefaultPath() {
        return to_(getRequestMapping());
    }
    
    /**
     * <p>
     * Method ：converPrefix
     * <p>
     * Description : 
     * 1: "path" -> "path/path_"，便于区分每个模块的jsp文件名
     * 2: "path/to" -> "path/to/to_"
     * 
     * @param prefix
     * @return
     * @author gulixing@msn.com
     * @version 1.0.0
     */
    public static String to_(String prefix) {
        if (!prefix.contains("/")) {// "regist"等直接量
            return prefix.concat("/").concat(prefix).concat("_");
        }
    	return prefix+"/"+StringUtils.substringAfter(prefix, "/")+"_";
    }
    
    private String getRequestMapping(){
        if(this.getClass().getAnnotation(RequestMapping.class)!=null){
            return this.getClass().getAnnotation(RequestMapping.class).value()[0];
        }
        return "";
    }

    /**
     * <p>Method ：toJson
     * <p>Description : 未防止xss已对内容进行html转码处理
     * @param model
     * @return 
     * @author  gulixing@msn.com
     * @version 1.0.0
     */
    public String toJson(Object model) {
    	return JsonKit.toJson(model);
    }
    
    public String toJsonEscaped(Object model) {
//        //解决html转码后导致引号转义的问题
        return StringEscapeUtils.escapeHtml4(toJson(model)).replace("&quot;", "\"");
    }
    
    protected  Object getCurrentUserPrincipal() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            return authentication.getPrincipal();
        }
        return null;
    }
    
    /**
     * <p>Method ：setModelAttrFromRequest
     * <p>Description : 将request中parameter属性提取，并自动对Model对象赋值
     * @param m
     * @param request 
     * @author  顾力行-gulixing@msn.com
     */
    protected void setModelAttrFromRequest(BaseModel m, HttpServletRequest request){
        setModelAttrFromRequest(m, request, "");
    }
    
    /**
     * <p>Method ：setModelAttrFromRequest
     * <p>Description : 将request中parameter属性提取，并自动对Model对象赋值
     *
     * @param m
     * @param request
     * @param exclude  排除的字段
     * @author  顾力行-gulixing@msn.com
     */
    protected void setModelAttrFromRequest(BaseModel m, HttpServletRequest request,String exclude){
        for(Iterator iter =  request.getParameterMap().entrySet().iterator();iter.hasNext();){    
            Entry element = (Entry)iter.next();    
            String strKey = element.getKey().toString();   
            if(!isExcluded(strKey,exclude)){
                String[] value=(String[])element.getValue();  
                m.set(strKey, (String)value[0]); 
            }
        }  
    }
    
    private static boolean isExcluded(String key,String ex){
    	String arr[] = ex.split(",");
    	for (String string : arr) {
			if(key.equals(string)){
				return true;
			}
		}
    	return false;
    }
    
    public static void main(String[] args) {
    	System.out.println(isExcluded("ab", "abc,def"));//false
    	System.out.println(isExcluded("abc", "abc,def"));//true
    	System.out.println(StringUtils.containsAny("abcd", "ab","cd"));
        System.out.println(to_("regist"));//regist/regist_
        System.out.println(to_("yourapp/demo"));//yourapp/demo/demo_
        System.out.println(HtmlEscapers.htmlEscaper().escape("a>b"));
    }
}
